/*
 * Title:        CloudScheduler Toolkit
 * Description:  a Toolkit for Modeling and Simulation of Job Scheduling and Resource Provisioning in Cloud System
 * Licence:      GPL - http://www.gnu.org/copyleft/gpl.html
 * Author:       Fuhui Wu
 *
 * Copyright (c) 2013-2014, The National University of Defense Technology, China
 */

package org.nudt.jCloud.jobScheduler;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.nudt.jCloud.infrastructure.Slot;
import org.nudt.jCloud.infrastructure.SlotType;
import org.nudt.jCloud.simulation.Request;
import org.nudt.jCloud.simulation.RequestData;
import org.nudt.jCloud.simulation.SchedBatchSet;
import org.nudt.jCloud.simulation.VirtSlotAlloc;
import org.nudt.jCloud.workload.Job;
import org.nudt.jCloud.workload.Task;

public class LocalityDelayScheduler extends JobScheduler{
	private int skipCount;
	private Map<Job, Integer> jobDelayCount;

	public LocalityDelayScheduler(String name, int skipCount) {
		super(name);
		jobDelayCount = new HashMap<Job, Integer>();
		setSkipCount(skipCount);
	}

	@Override
	public void assignTaskR(RequestData requestData, SchedBatchSet schedBatchSet) {
		requestData.sortByScheduledInc();;
		List<Request> requestList = requestData.getRequestList();
		SlotType slotType = requestList.get(0).getJob().getSlotType();
		Slot slot = getFrwk().getOneFreeSlot(slotType);
		while(slot != null){
			Task selectTask = null;
			for(Request request : requestList){
				if(request.getUnAssignedTasks().size()>0){
					for(Task task : request.getUnAssignedTasks()){
						if(task.getBlock().locality(slot)){
							selectTask = task;
							break;
						}
					}
					if(selectTask == null){
						if(jobDelayCount.containsKey(request.getJob())){
							int count = jobDelayCount.get(request.getJob());
							if(count>=skipCount){
								selectTask = request.getUnAssignedTasks().get(0);
								jobDelayCount.remove(request.getJob());
							}else{
								count += 1;
								jobDelayCount.put(request.getJob(), count);
							}
						}else{
							jobDelayCount.put(request.getJob(), 1);
						}
					}
				}
				if(selectTask != null){
					assignTasktoSlot(request, selectTask, slot, schedBatchSet);
					break;
				}
			}
			if(selectTask == null){
				break;
			}
			slot = getFrwk().getOneFreeSlot(slotType);
		}
	}

	@Override
	public void assignTaskS(RequestData requestData, VirtSlotAlloc virtSlotAlloc) {
		
	}

	public Map<Job, Integer> getJobDelayCount() {
		return jobDelayCount;
	}

	public void setJobDelayCount(Map<Job, Integer> jobDelayCount) {
		this.jobDelayCount = jobDelayCount;
	}

	public int getSkipCount() {
		return skipCount;
	}

	public void setSkipCount(int skipCount) {
		this.skipCount = skipCount;
	}

}
